#ifndef game_c
#define game_c

/*

file:    game.c - share functions
author:  feitian16
date:    2012-10-21
Version: 1.0.1
Email:   feitian16@gmail.com

*/


#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

#include "define.h"

#include "game.h"
#include "cpu.h"
#include "draw.h"
#include "menu.h"


//Login Dialog
#define login_title "Login"

//End Messages
#define cpu_win "Computer win !"
#define no_win "NO cels,No winners !"
#define end_title "The End"

//Confirm Exit Dialog
#define exit_title "Confirm exit "
#define exit_label "Please confirm exit "

//Data structures
GSList *Lgrup1,*Lgrup2; //Login group
GtkWidget *radio11,*radio12,*radio21,*radio22; //Radio items

gint scaleX=15;//X scale
gint scaleO=15;//O scale
gint scaleGrid=40;//table scale
gint gameMode=0;//GameMode： 0 --- Player VS PC; 1--- Player1 VS Player2
gint gameStatus=0;//GameStatust:0----Game continue;1----CPU Win;2---- User Win;3---- No win
gchar player1char='X',player2char='O';//Players Chars (default values)
gint gstepNumber=0;//the Number of Game Steps

//Code
void setAI(GtkWidget *widget,gpointer data)
{
    //Set Game Mode as AI: Player VS PC
   gameMode=0;
}

void setPlayers(GtkWidget *widget,gpointer data)
{
  //Set Game Mode as Players: Player1 VS PPlayer2
  gameMode=1;
}

void setX(GtkWidget *widget,gpointer data)
{
  //Set X Char for Player
  player1char='X';
  player2char='O';
}

void setO(GtkWidget *widget, gpointer data)
{
//Set O char for Player
player1char='O';
player2char='X';
}



int confirm_exit_dialog(void)
{
	//Confirm exit dialog
	GtkWidget *dialog;
	GtkWidget *label;
	gint result;

	//Confirm Exit from GAME
	#if debug
	g_printf("Show confirmation dialog !\n");
	#endif

	dialog = gtk_dialog_new_with_buttons (exit_title,GTK_WINDOW(window),GTK_DIALOG_MODAL,GTK_STOCK_YES,GTK_RESPONSE_ACCEPT,GTK_STOCK_NO,GTK_RESPONSE_REJECT,NULL);
	gtk_window_set_policy(GTK_WINDOW(dialog),FALSE,FALSE,TRUE);
	//Add text in dialog
	label=gtk_label_new(exit_label);
	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),label);
	//Show dialolg
	gtk_widget_show_all (dialog);
	if (gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT)
		    result=1;
		    else
		    result=0;
	gtk_widget_destroy(dialog);
	return result;
}

gint delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
{
	//Confirm Exit from GAME
	#if debug
	g_printf("Delete event !\n");
	#endif
	if (confirm_exit_dialog())
		return FALSE;
	else
		return TRUE;
}

void destroy(GtkWidget *widget,gpointer data)
{
	//Stop program
	#if debug
	g_printf("Exit\n");
	#endif
	gtk_main_quit();
}

gboolean redraw(void)
{
	//Redraw objects
	drawGrid();
	return TRUE;
}

gboolean Game_action(GtkWidget *event_box,GdkEventButton *event,gpointer data)
{
    #if debug
    g_printf("GameMode=%d (0 --- Player VS PC; 1--- Player1 VS Player2)\n",gameMode);
    #endif

    gint i,j;

    //Calc coords
    i=(gint)(event->x)/scaleGrid;
    j=(gint)(event->y)/scaleGrid;

    if(gameMode==0)
    {
        Game_actionAI(i,j);
    }
    else if(gameMode==1)
    {
        Game_actionPlayers(i,j);
    }
}

gboolean Game_actionAI(gint x,gint y)
{
    gint i,j,r;
    i=x,j=y;
    playermove(i,j,player1char);//Player1 Move
    r=showresult();
    if (r==0) //If CPU can move
    {
        cpumove();//CPU Move
        showresult();
    }
    gstepNumber=gstepNumber++;
    return TRUE;
}

gboolean Game_actionPlayers(gint x,gint y)
{
    gint i,j;
    i=x,j=y;

    if(0==gstepNumber%2&&gameStatus==0)//Player1 Move
    {
        playermove(i,j,player1char);

        #if debug
        g_printf("Player1 Move %c;\n",player1char);
        #endif

        gameStatus=showresult();
    }
    else if(1==gstepNumber%2&&gameStatus==0)//Player2 Move
    {
        playermove(i,j,player2char);

        #if debug
        g_printf("Player2 Move %c;\n",player2char);
        #endif

        gameStatus=showresult();
    }

    gstepNumber=gstepNumber++;

    return TRUE;
}

void playermove(gint x,gint y,gchar movechar)
{
    gint i,j;
    gchar mchar;

    i=x,j=y,mchar=movechar;
    if (grid[i][j]==' ')//Check if cell is free
    {
        grid[i][j]=mchar;//Marc cell as used

        #if debug
        g_printf("playerchar grid: %d  %d;\n",i,j);
        #endif

        drawGrid();//Show on modifications
    }
}

int checkwin(void)
{
	/*
	Check game status
	0 - Game continue
	1 - CPU Win
	2 - User Win
	3 - No win 
	*/

        gint i,j,n,k;
        gchar s1[6],cpustr[6],usrstr[6];

        for(i=0;i<5;i++)
	{
                cpustr[i]=player2char;
                usrstr[i]=player1char;
	}	
        cpustr[5]='\0';
        usrstr[5]='\0';

	#if debug
        printf("player2char:%s \n",cpustr);
        printf("player1char:%s \n",usrstr);
	#endif	

	//Check lines
        for(i=0;i<15;i++)
        {
            s1[0]='\0';
            for(k=0;k<11;k++)
            {
                for(j=k;j<5+k;j++)
                        s1[j-k]=grid[i][j];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                        return 1;
                if (strcmp(s1,usrstr)==0)
                        return 2;
            }
        }
/*
	//Check columns
        for(i=0;i<15;i++)
	{
            s1[0]='\0';
            for(k=0;k<11;k++)
            {
                for(j=k;j<5+k;j++)
                            s1[j-k]=grid[j][i];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                            return 1;
                if (strcmp(s1,usrstr)==0)
                            return 2;
            }
	}
*/
        //Check columns
        for(j=0;j<15;j++)
        {
            s1[0]='\0';
            for(k=0;k<11;k++)
            {
                for(i=k;i<5+k;i++)
                            s1[i-k]=grid[i][j];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                            return 1;
                if (strcmp(s1,usrstr)==0)
                            return 2;
            }
        }

 /*
Verificam Check diagonals:Frome 1 to 3
 1******2
 *            *
 4******3
*/
	s1[0]='\0';
        for(k=0;k<11;k++)
        {
            for(j=0;j<11-k;j++)
            {
                for(i=j;i<5+j;i++)
                        s1[i-j]=grid[i+k][i];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                            return 1;
                if (strcmp(s1,usrstr)==0)
                            return 2;
            }
        }

        s1[0]='\0';
        for(k=0;k<11;k++)
        {
            for(j=0;j<11-k;j++)
            {
                for(i=j;i<5+j;i++)
                        s1[i-j]=grid[i][i+k];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                            return 1;
                if (strcmp(s1,usrstr)==0)
                            return 2;
            }
        }

        //Verificam Check diagonals:Frome 2 to 4
        s1[0]='\0';
        for(k=0;k<11;k++)
        {
            for(j=0;j<11-k;j++)
            {
                for(i=j;i<5+j;i++)
                        s1[i-j]=grid[i+k][14-i];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                            return 1;
                if (strcmp(s1,usrstr)==0)
                            return 2;
            }
        }

        s1[0]='\0';
        for(k=0;k<11;k++)
        {
            for(j=0;j<11-k;j++)
            {
                for(i=j;i<5+j;i++)
                        s1[i-j]=grid[i][14-k-i];
                s1[5]='\0';
                if (strcmp(s1,cpustr)==0)
                            return 1;
                if (strcmp(s1,usrstr)==0)
                            return 2;
            }
        }
        printf("check win s1:%s \n",s1);

        //Check if exist Free cels
        n=0;
        for (i=0;i<15;i++)
        for (j=0;j<15;j++)
                if (grid[i][j]!=' ')
                        n++;
        #if debug
        printf("Total fill cell : %d\n",n);
        #endif
        if (n==225)
                return 3;
/*    //Check if exist Free cels
        n=225;
        for (i=0;i<15;i++)
        for (j=0;j<15;j++)
                if (grid[i][j]=' ')
                {
                        n=1;
                        break;
                }
        if (n==225)
                return 3;
*/
        return 0;
}

int showresult(void)
{
    gint x;
    GtkWidget *dialog,*label;

    x=checkwin();

   #if debug
   g_printf("Check win value  : %d\n",x);
   #endif

    if (x!=0)//If win show dialog
   {
       dialog = gtk_dialog_new_with_buttons (end_title,GTK_WINDOW(window),GTK_DIALOG_MODAL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
       gtk_window_set_policy(GTK_WINDOW(dialog),FALSE,FALSE,TRUE);

       gtk_widget_set_size_request(dialog,120,100);

        //Set a mesage
        if (x==1)
        {
           if(gameMode==0)
           {
                strcpy(player_win,cpu_win);
           }
           else if(gameMode==1)
           {
               strcpy(player_win,"Winer : ");
               strcat(player_win,user2name);
           }
            label=gtk_label_new (player_win);
        }
        if (x==2)
        {
           strcpy(player_win,"Winer : ");
           strcat(player_win,user1name);
           label=gtk_label_new (player_win);
        }
        if (x==3)
        label=gtk_label_new (no_win);

       //Add text in dialog
       gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),label);
       //Show dialog
       gtk_widget_show_all (dialog);

       if(gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_OK|GTK_RESPONSE_CLOSE)
            gtk_widget_destroy(dialog);   
       return 1;
   }
     return 0;
}

void init_game(void)
{
	int i,j;
	//Initializing . . .
	for(i=0;i<15;i++)
	for(j=0;j<15;j++)
	grid[i][j]=' ';
        gameMode=0;
        gameStatus=0;
	//Init random generator
        //srand(time(NULL));
}

void login(void)
{
    //Login Dialog widgets
    GtkWidget *Ldialog; //Login dialog
    GtkWidget *Llabel1,*Llabel2,*Llabel3,*Llabel4,*Llabel5; //Login dialog labels
    GtkWidget *Ledit1,*Ledit2;//Edit box
    GtkWidget *Ltable;//Login table

    GtkWidget *msg;//Login Message
    gchar username[10];

    int ok=1;

    Ldialog = gtk_dialog_new_with_buttons (login_title,GTK_WINDOW(window),GTK_DIALOG_MODAL,
                                         GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,NULL);
    gtk_window_set_resizable(GTK_WINDOW(Ldialog),TRUE);//Set Window Policy

    gtk_widget_set_size_request(Ldialog,450,300);
    gtk_container_set_border_width (GTK_CONTAINER (Ldialog), 5);

    Llabel1 = gtk_label_new (Name_msg);
    Llabel2 = gtk_label_new(Mode_msg);
    Llabel3 = gtk_label_new(Chess_msg);
    Llabel4 = gtk_label_new(Player2name_msg);
    Llabel5 = gtk_label_new(Name2_msg);

    Ledit1=gtk_entry_new_with_max_length(10);
    gtk_entry_set_text(GTK_ENTRY(Ledit1),"Michael");

    Ledit2=gtk_entry_new_with_max_length(10);
    gtk_entry_set_text(GTK_ENTRY(Ledit2),"Susan");

    radio11 = gtk_radio_button_new_with_label (NULL, "AI");
    Lgrup1 = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio11));
    radio12 = gtk_radio_button_new_with_label( Lgrup1, "Players");

    g_signal_connect(G_OBJECT(radio11),"clicked",G_CALLBACK(setAI),NULL);
    g_signal_connect(G_OBJECT(radio12),"clicked",G_CALLBACK(setPlayers),NULL);

    radio21 = gtk_radio_button_new_with_label (NULL, "X");
    Lgrup2 = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio21));
    radio22 = gtk_radio_button_new_with_label( Lgrup2, "O");

    g_signal_connect(G_OBJECT(radio21),"clicked",G_CALLBACK(setX),NULL);
    g_signal_connect(G_OBJECT(radio22),"clicked",G_CALLBACK(setO),NULL);

    Ltable=gtk_table_new(5,3,FALSE);

    gtk_table_attach_defaults (GTK_TABLE (Ltable), Llabel1, 0, 1, 0, 1);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), Llabel2, 0, 1, 1, 2);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), Llabel3, 0, 1, 2, 3);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), Ledit1, 1, 3, 0, 1);

    gtk_table_attach_defaults (GTK_TABLE (Ltable), radio11, 1, 2, 1, 2);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), radio12, 2, 3, 1, 2);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), radio21, 1, 2, 2, 3);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), radio22, 2, 3, 2, 3);

    gtk_table_attach_defaults (GTK_TABLE (Ltable), Llabel4, 0, 3, 3, 4);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), Llabel5, 0, 1, 4, 5);
    gtk_table_attach_defaults (GTK_TABLE (Ltable), Ledit2, 1, 3, 4, 5);


    gtk_container_add (GTK_CONTAINER (GTK_DIALOG(Ldialog)->vbox),Ltable);
    //Show dialog
    gtk_widget_show_all(Ldialog);
    //Process events form dialog
    do
    {
        ok=0;
        //Run dialog
        while( gtk_dialog_run (GTK_DIALOG (Ldialog))!=GTK_RESPONSE_ACCEPT) ;
        //Get infor from Dialog
        strcpy(username,gtk_entry_get_text(GTK_ENTRY(Ledit1)));
        //If UserName is Empty
        if (strlen(username)==0)
        {
              //Show Warning Message
              msg=gtk_message_dialog_new (GTK_WINDOW(window),
                                          GTK_DIALOG_MODAL,
                                          GTK_MESSAGE_INFO,
                                          GTK_BUTTONS_OK,
                                          error_name_msg);
              gtk_dialog_run(GTK_DIALOG(msg));
              gtk_widget_destroy(msg);
              ok=1; //Loop will not stop
        }
        else
        {
          //Register user name
          strcpy(user1name,username);
        }

        #if debug
        printf("Player1 Name : %s\n",username);
        #endif

        if(gameMode==1)
        {
            strcpy(username,gtk_entry_get_text(GTK_ENTRY(Ledit2)));
            if(strlen(username)==0)
            {
                //Show Warning Message
                msg=gtk_message_dialog_new (GTK_WINDOW(window),
                                            GTK_DIALOG_MODAL,
                                            GTK_MESSAGE_INFO,
                                            GTK_BUTTONS_OK,
                                            error_name_msg);
                gtk_dialog_run(GTK_DIALOG(msg));
                gtk_widget_destroy(msg);
                ok=1; //Loop will not stop
            }
            else
            {
              //Register user name
              strcpy(user2name,username);
            }

            #if debug
            printf("Player2 Name : %s\n",username);
            #endif
        }
    }
    while(ok);
    //Destroy dialog
    gtk_widget_destroy(Ldialog);
}

void initcolors(void)
{
	//Init Colors 
	//Gen colors for X and O
	//Color for X
	Xcolor=gdk_gc_new(darea->window);
	color.red=65535;//Red color
	color.green=0;
	color.blue=0;
	gdk_gc_set_rgb_fg_color (Xcolor, &color);
	//Color for O
	Ocolor=gdk_gc_new(darea->window);
	color.red=0;
        color.green=65535;//Color Green
        color.blue=0;
	gdk_gc_set_rgb_fg_color (Ocolor, &color);
}
#endif
